﻿using Common.Builders.Interfaces;
using Common.Entities;
using Common.ServiceResponse;
using Common.Utils.Constants;
using Infrastructure.Interfaces;

namespace AuthenticationService
{
    public class AuthenticationService : IAuthenticationService
    {
        private readonly IUserAuthenticationProvider _userAuthenticationProvider;
        private readonly IResponseDetailsService _responseDetailsService;
        private IUserBuilder _userBuilder;
        private readonly IUserRegistrationProvider _userRegistrationProvider;
        private readonly IUserAccountValidator _userAccountValidator;

        public AuthenticationService(IUserAuthenticationProvider userAuthenticationProvider,
                                     IResponseDetailsService responseDetailsService,
                                     IUserBuilder userBuilder,
                                     IUserRegistrationProvider userRegistrationProvider,
                                     IUserAccountValidator userAccountValidator)
        {
            _userAuthenticationProvider = userAuthenticationProvider;
            _responseDetailsService = responseDetailsService;
            _userBuilder = userBuilder;
            _userRegistrationProvider = userRegistrationProvider;
            _userAccountValidator = userAccountValidator;
        }

        public User LogUserIn(User user)
        {
            _userBuilder = _userBuilder.WithUserName(user.UserName);
            var incorrectUserNameResponseDetails = _responseDetailsService.BuildWarningResponse(BusinessWarningDescription.IncorrectUserNameOrPassword);
            var successResponseDetails = _responseDetailsService.BuildSuccessResponse();
            var unknownErrorResponseDetails = _responseDetailsService.BuildWarningResponse(BusinessWarningDescription.UnknownErrorOccuredOnServer);

            if (!IsUsernameAndPasswordValid(user.UserName, user.Password))
            {
                return _userBuilder.WithResponseDetails(incorrectUserNameResponseDetails).Build();
            }

            if (_userAuthenticationProvider.LogUserIn(user))
                {
                    var securityKey = _userAuthenticationProvider.CreateSecurityKey(user);
                    if (securityKey != null)
                    {
                        return _userBuilder.WithSecurityKey(securityKey).WithResponseDetails(successResponseDetails).Build();
                    }
                    return _userBuilder.WithResponseDetails(unknownErrorResponseDetails).Build();
                }

            return _userBuilder.WithResponseDetails(incorrectUserNameResponseDetails).Build();
        }

        public ResponseDetails RegistrateUser(User user)
        {
            if (IsUsernameAndPasswordValid(user.UserName, user.Password))
            {

                if (_userAuthenticationProvider.UserExists(user.UserName))
                {
                    return _responseDetailsService.BuildWarningResponse(BusinessWarningDescription.UserWithSuchNameAlreadyExists);
                }

                if (_userRegistrationProvider.Registrate(user))
                {
                    return _responseDetailsService.BuildSuccessResponse();
                }

                return _responseDetailsService.BuildErrorResponse(BusinessWarningDescription.UnknownErrorOccuredOnServer);
            }
            return _responseDetailsService.BuildWarningResponse(BusinessWarningDescription.IncorrectUserNameOrPassword);
        }

        public ResponseDetails LogUserOut(User user)
        {
            if (_userAuthenticationProvider.LogUserOut(user))
            {
                return _responseDetailsService.BuildSuccessResponse();
            }
            return _responseDetailsService.BuildErrorResponse(BusinessWarningDescription.UnknownErrorOccuredOnServer);
        }

        private bool IsUsernameAndPasswordValid(string userName, string password)
        {
            return _userAccountValidator.IsUsernameValid(userName) && _userAccountValidator.IsPasswordValid(password);
        }
    }
}
